#pragma once

#include "rock.h"
#include "cell.h"

class solitaire : public QGraphicsScene
{
    Q_OBJECT

public:
    static const qreal CELL_SPACE;
    static const qreal CELL_RADIUS;
    static const qreal ROCK_RADIUS;

public:
    solitaire(int field_size, int corner_size, QWidget *parent = 0);
    ~solitaire();

public:
    QPointF center_coord(const QPoint &p)
    {
        return QPointF((qreal(p.x()) + qreal(0.5)) * CELL_SPACE * 2, (qreal(p.y()) + qreal(0.5)) * CELL_SPACE * 2);
    }

    void reset_last_cell();
    void drop_rock(rock &r);

protected slots:
    void drag_rock(rock_ptr r, const QPointF &pos);
    void drop_rock(rock_ptr r);

private:
    bool check_location(const QPoint &p) const;
    cell_ptr create_cell(const QPoint &p);
    rock_ptr create_rock(const QPoint &p);
    void highlight_cell(const_rock_ptr r, cell_ptr c);
    bool can_move_rock(const_rock_ptr r, const_cell_ptr c, rock_ptr *victim) const;

private:
    int coord2index(const QPoint &p) const
    {
        return (p.y() * field_size_ + p.x());
    }

    cell_ptr &cell_ref(const QPoint &p)
    {
        return cells_[coord2index(p)];
    }

    rock_ptr &rock_ref(const QPoint &p)
    {
        return rocks_[coord2index(p)];
    }

    const cell_ptr &cell_ref(const QPoint &p) const
    {
        return cells_[coord2index(p)];
    }

    const rock_ptr &rock_ref(const QPoint &p) const
    {
        return rocks_[coord2index(p)];
    }

    bool check_location(const QPoint &p)
    {
        if (p.x() >= corner_size_ && p.x() < field_size_ - corner_size_)
            return true;
        if (p.y() >= corner_size_ && p.y() < field_size_ - corner_size_)
            return true;
        return false;
    }


private:
    int field_size_;
    int corner_size_;
    vector<cell_ptr> cells_;
    vector<rock_ptr> rocks_;
    cell *last_cell_;
};


